<?php 

namespace IMT\ServicesBundle\Controller;

use JMS\Serializer\SerializationContext;

use IMT\Plugins\ParticipantsBundle\Entity\ParticipantEvent;

use Symfony\Component\HttpFoundation\Request;

use Symfony\Component\Security\Core\Exception\AccessDeniedException;
use Symfony\Component\Routing\Exception\MethodNotAllowedException;
use Symfony\Component\Security\Core\Exception\AuthenticationException;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use FOS\RestBundle\View\View;
use FOS\Rest\Util\Codes;

class ParticipantRestController extends Controller
{
	/**
	 * GET /event/{eventId}
	 *
	 * @param string $eventId
	 * @return Response
	 */
	public function getParticipantAction($id)
	{			
		if(intval($id) == 0)
	    	throw new \InvalidArgumentException(400, 'L\'id est incorrect : '.$id);
	    
    	// Récupération de l'event
    	$repository = $this->getDoctrine()->getRepository('IMTPluginsParticipantsBundle:ParticipantEvent');
   		$participant = $repository->find($id);
   		
   		if (!$participant || !$participant->getEvent())
   			throw new NotFoundHttpException('Le participant ayant l\'id '.$id.' n\'existe pas');
   		
   		
   		// Vérification des droits d'acces
   		$securityContext = $this->get('security.context');
   		
   		if(false === $securityContext->isGranted('VIEW', $participant->getEvent())){
   			throw new AccessDeniedException(403, 'Acces refuse pour '.$securityContext->getToken()->getUser()->getUsername());
   		}

   		$context = new SerializationContext();
   		$context->setVersion('1.0');
   		$context->setGroups(array('participant_details', 'participant_event_list', 'contact_list'));
   		   		
		$view = View::create()
			->setStatusCode(200)
			->setData($participant)
			->setSerializationContext($context);

		return $this->get('fos_rest.view_handler')->handle($view);
	}
	
	/**
	 * Creates a new Thread from the submitted data.
	 *
	 * @param Request $request The current request
	 *
	 * @return View
	 */
	public function postParticipantAction(Request $request)
	{		
		$idParticipant = 0;
		
		$em = $this->getDoctrine()->getEntityManager();
		$viewHandler = $this->get('fos_rest.view_handler');
			
		if('POST' == $request->getMethod()){
			$idParticipant = $request->request->get('idParticipant');
			$idAccount = $request->request->get('idAccount');
			$idContact = $request->request->get('idContact');
			$idEvent = $request->request->get('idEvent');
			
			$account = $em->getRepository('IMTAccountBundle:Account')->find($idAccount);
			if(!$account)
				throw $this->createNotFoundException('Le compte "'.$idAccount.'" n\'existe pas');
			
			$contact = $em->getRepository('IMTUserBundle:Contact')->find($idContact);
			if(!$contact)
				throw $this->createNotFoundException('Le contact "'.$idContact.'" n\'existe pas');
			
			$event = $em->getRepository('IMTUserBundle:Contact')->find($idEvent);
			if(!$event)
				throw $this->createNotFoundException('L\'événement "'.$idEvent.'" n\'existe pas');
			
			// Vérification des droits d'acces
			$securityContext = $this->get('security.context');
			 
			if(false === $securityContext->isGranted('VIEW', $event)){
				throw new AccessDeniedException(403, 'Acces refuse pour '.$securityContext->getToken()->getUser()->getUsername());
			}
			
			$validator = $this->get('validator');
			$repository = $em->getRepository('IMTEventBundle:BaseEvent');
		
			if($idParticipant == 0){
				$participant = new ParticipantEvent();
			} else {
				$participant = $repository->find($idParticipant);
				 
				if(!$participant)
					throw $this->createNotFoundException('Le participant à modifier n\'existe pas');
			}
			
			$participant->setAccount($account);
			$participant->setEvent($event);
			$participant->setParticipant($contact);
			$participant->setParticipationState($request->request->get('participationState'));
			
			$errors = $validator->validate($participant);
			 
			if(count($errors) > 0){
				$return['errors'] = $errors;
				
				return $viewHandler->handle($this->createErrorViewResponse($return));
			} else {
				$em->persist($participant);
				$em->flush();
				 
				$return['idParticipant'] = $participant->getId();
				
				return $viewHandler->handle($this->createSuccessViewResponse($return));
			}
		} else {
			throw new MethodNotAllowedException('POST');
		}
	
	}
	
	public function deleteParticipantAction($id)
	{
		if(intval($id) == 0)
	    	throw new \InvalidArgumentException(400, 'L\'id est incorrect : '.$id);
		
		$em = $this->getDoctrine()->getEntityManager();
		
    	// Récupération de l'event
    	$repository = $em->getRepository('IMTPluginsParticipantsBundle:ParticipantEvent');
   		$participant = $repository->find($id);
   		
   		if (!$participant)
   			throw new NotFoundHttpException('Le participant ayant l\'id '.$id.' n\'existe pas');
   		
   		// Vérification des droits d'acces
   		$securityContext = $this->get('security.context');
   		
   		if($participant->getEvent() && false === $securityContext->isGranted('VIEW', $participant->getEvent())){
   			throw new AccessDeniedException(403, 'Acces refuse pour '.$securityContext->getToken()->getUser()->getUsername());
   		}
   		
		$viewHandler = $this->get('fos_rest.view_handler');
   			
		$em->remove($participant);
		$em->flush();
	
		return $viewHandler->handle($this->createSuccessViewResponse(array('idParticipant' => $id)));
	}
	
	private function createSuccessViewResponse($return)
	{
		$view = View::create()
			->setStatusCode(200)
			->setData($return);
		
		return $view;
	}	
	
	private function createErrorViewResponse($return)
	{
		$view = View::create()
			->setStatusCode(Codes::HTTP_BAD_REQUEST)
			->setData($return);
	
		return $view;
	}
}